home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / dsp / dspkgctr.z / dspkgctr / gcc / print-tree.c < prev    next >
C/C++ Source or Header  |  1992-06-08  |  16KB  |  658 lines

  1. /* Prints out tree in human readable form - GNU C-compiler
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20.  
  21. #include "config.h"
  22. #include "tree.h"
  23. #include <stdio.h>
  24.  
  25.  
  26. /* Names of tree components.
  27.    Used for printing out the tree and error messages.  */
  28. #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
  29.  
  30. char *tree_code_name[] = {
  31. #include "tree.def"
  32. };
  33. #undef DEFTREECODE
  34.  
  35. extern char *tree_code_type[];
  36. extern int tree_code_length[];
  37. extern char *mode_name[];
  38.  
  39. extern char spaces[];
  40.  
  41. #define MIN(x,y) ((x < y) ? x : y)
  42.  
  43. static FILE *outfile;
  44.  
  45. extern int tree_node_counter;
  46.  
  47. /* markvec[i] is 1 if node number i has been seen already.  */
  48.  
  49. static char *markvec;
  50.  
  51. static void dump ();
  52. void dump_tree ();
  53.  
  54. void
  55. debug_dump_tree (root)
  56.      tree root;
  57. {
  58.   dump_tree (stderr, root);
  59. }
  60.  
  61. void
  62. dump_tree (outf, root)
  63.      FILE *outf;
  64.      tree root;
  65. {
  66.   markvec = (char *) alloca (tree_node_counter + 1);
  67.   bzero (markvec, tree_node_counter + 1);
  68.   outfile = outf;
  69.   dump (root, 0);
  70.   fflush (outf);
  71. }
  72.  
  73. static
  74. void
  75. wruid (node)
  76.      tree node;
  77. {
  78.  
  79.   if (node == NULL)
  80.     fputs ("<>", outfile);
  81.   else {
  82.     fprintf (outfile, "%1d", TREE_UID (node));
  83.   }
  84. }
  85.  
  86. static 
  87. void
  88. part (title, node)
  89.      char title[];
  90.      tree node;
  91. {
  92.   fprintf (outfile, " %s = ", title);
  93.   wruid (node);
  94.   putc (';', outfile);
  95. }
  96.  
  97. /* Similar to `part' but prefix with @ if value is not constant
  98.    and print the constant value if it is constant.  */
  99. static
  100. void
  101. cpart (title, ct, punct)
  102.      char *title;
  103.      tree ct;
  104.      char punct;
  105. {
  106.   fprintf (outfile, " %s = ", title);
  107.   if (ct == NULL)
  108.     fputs ("<>", outfile);
  109.   else
  110.     {
  111.       if (!TREE_LITERAL (ct))
  112.     {
  113.       putc ('@', outfile);
  114.       wruid (ct);
  115.     }
  116.       else
  117.     fprintf (outfile, "%ld", TREE_INT_CST_LOW (ct));
  118.     }
  119.   putc (punct, outfile);
  120. }
  121.  
  122. static
  123. void
  124. walk (node, leaf, indent)
  125.      tree node;
  126.      tree leaf;
  127.      int indent;
  128. {
  129.   if (node != NULL)
  130.     dump (node, indent+1);
  131. }
  132.  
  133. static void
  134. cwalk (s, leaf, indent)
  135.      tree s;
  136.      tree leaf;
  137.      int indent;
  138. {
  139.   if (s != NULL) 
  140.     if (!TREE_LITERAL (s))
  141.       walk (s, leaf, indent);
  142. }
  143.  
  144. static void
  145. prtypeinfo (node)
  146.      register tree node;
  147. {
  148.   int first;
  149.   
  150.   part ("type", TREE_TYPE (node));
  151.   first = 1;
  152.   fputs (" [", outfile);
  153.   if (TREE_EXTERNAL (node))
  154.     {
  155.       if (!first) putc (' ', outfile);
  156.       fputs ("external", outfile);
  157.       first = 0;
  158.     }
  159.   if (TREE_PUBLIC (node))
  160.     {
  161.       if (!first) putc (' ', outfile);
  162.       fputs ("public", outfile);
  163.       first = 0;
  164.     }
  165.   if (TREE_STATIC (node))
  166.     {
  167.       if (!first) putc (' ', outfile);
  168.       fputs ("static", outfile);
  169.       first = 0;
  170.     }
  171.   if (TREE_VOLATILE (node))
  172.     {
  173.       if (!first) putc (' ', outfile);
  174.       fputs ("volatile", outfile);
  175.       first = 0;
  176.     }
  177.   if (TREE_PACKED (node))
  178.     {
  179.       if (!first) putc (' ', outfile);
  180.       fputs ("packed", outfile);
  181.       first = 0;
  182.     }
  183.   if (TREE_READONLY (node))
  184.     {
  185.       if (!first) putc (' ', outfile);
  186.       fputs ("readonly", outfile);
  187.       first = 0;
  188.     }
  189.   if (TREE_LITERAL (node))
  190.     {
  191.       if (!first) putc (' ', outfile);
  192.       fputs ("literal", outfile);
  193.       first = 0;
  194.     }
  195.   if (TREE_NONLOCAL (node))
  196.     {
  197.       if (!first) putc (' ', outfile);
  198.       fputs ("nonlocal", outfile);
  199.       first = 0;
  200.     }
  201.   if (TREE_ADDRESSABLE (node))
  202.     {
  203.       if (!first) putc (' ', outfile);
  204.       fputs ("addressable", outfile);
  205.       first = 0;
  206.     }
  207.   if (TREE_REGDECL (node))
  208.     {
  209.       if (!first) putc (' ', outfile);
  210.       fputs ("regdecl", outfile);
  211.       first = 0;
  212.     }
  213.   if (TREE_THIS_VOLATILE (node))
  214.     {
  215.       if (!first) putc (' ', outfile);
  216.       fputs ("this_vol", outfile);
  217.       first = 0;
  218.     }
  219.   if (TREE_UNSIGNED (node))
  220.     {
  221.       if (!first) putc (' ', outfile);
  222.       fputs ("unsigned", outfile);
  223.       first = 0;
  224.     }
  225.   if (TREE_ASM_WRITTEN (node))
  226.     {
  227.       if (!first) putc (' ', outfile);
  228.       fputs ("asm_written", outfile);
  229.       first = 0;
  230.     }
  231.   if (TREE_INLINE (node))
  232.     {
  233.       if (!first) putc (' ', outfile);
  234.       fputs ("inline", outfile);
  235.       first = 0;
  236.     }
  237.   if (TREE_USED (node))
  238.     {
  239.       if (!first) putc (' ', outfile);
  240.       fputs ("used", outfile);
  241.       first = 0;
  242.     }
  243.   if (TREE_PERMANENT (node))
  244.     {
  245.       if (!first) putc (' ', outfile);
  246.       fputs ("permanent", outfile);
  247.       first = 0;
  248.     }
  249.   if (TREE_LANG_FLAG_1 (node))
  250.     {
  251.       if (!first) putc (' ', outfile);
  252.       fputs ("lang_flag_1", outfile);
  253.       first = 0;
  254.     }
  255.   if (TREE_LANG_FLAG_2 (node))
  256.     {
  257.       if (!first) putc (' ', outfile);
  258.       fputs ("lang_flag_2", outfile);
  259.       first = 0;
  260.     }
  261.   if (TREE_LANG_FLAG_3 (node))
  262.     {
  263.       if (!first) putc (' ', outfile);
  264.       fputs ("lang_flag_3", outfile);
  265.       first = 0;
  266.     }
  267.   if (TREE_LANG_FLAG_4 (node))
  268.     {
  269.       if (!first) putc (' ', outfile);
  270.       fputs ("lang_flag_4", outfile);
  271.       first = 0;
  272.     }
  273.   fputs ("] ", outfile);
  274. }
  275.  
  276. static void
  277. prdeclmodeinfo (node)
  278.      tree node;
  279. {
  280.   register enum machine_mode mode = DECL_MODE (node);
  281.   fprintf (outfile, " %s;", mode_name[(int) mode]);
  282.  
  283.   cpart ("size", DECL_SIZE (node), '*');
  284.   fprintf (outfile, "%d;", DECL_SIZE_UNIT (node));
  285.  
  286.   fprintf (outfile, " alignment = %1d;", DECL_ALIGN (node));
  287. }
  288.  
  289. static
  290. void
  291. prtypemodeinfo (node)
  292.      tree node;
  293. {
  294.   register enum machine_mode mode = TYPE_MODE (node);
  295.   fprintf (outfile, " %s;", mode_name[(int) mode]);
  296.  
  297.   cpart ("size", TYPE_SIZE (node), '*');
  298.   fprintf (outfile, "%d;", TYPE_SIZE_UNIT (node));
  299.  
  300.   fprintf (outfile, " alignment = %1d;", TYPE_ALIGN (node));
  301. }
  302.  
  303. static
  304. void
  305. skip (indent)
  306.      int indent;
  307. {
  308.   putc ('\n',outfile);
  309.   fputs (spaces + (strlen (spaces) - (12 + MIN (40,(indent+1)*2))), outfile);
  310. }
  311.  
  312. /* Output a description of the tree node NODE
  313.    if its description has not been output already.  */
  314.  
  315. static 
  316. void
  317. dump (node, indent)
  318.      tree node;
  319.      int indent;
  320. {
  321.   register enum tree_code code = TREE_CODE (node);
  322.   register int i;
  323.   register int len, first_rtl;
  324.   int nochain = 0;
  325.  
  326.   if (markvec[TREE_UID (node)])
  327.     return;
  328.   markvec[TREE_UID (node)] = 1;
  329.  
  330.   fputs ("   ", outfile);
  331.   fprintf (outfile, "%5d", TREE_UID (node));
  332.   fputs (spaces + (strlen (spaces) - MIN (40, (indent+1)*2)), outfile);
  333.   fputs (tree_code_name[(int) code], outfile);
  334.  
  335.   switch (*tree_code_type[(int) code])
  336.     {
  337.     case 'd':
  338.       fputs (" name = ", outfile);
  339.       if (DECL_NAME (node) == NULL)
  340.     fputs ("<>;", outfile);
  341.       else
  342.     fprintf (outfile, "%s;",
  343.          IDENTIFIER_POINTER (DECL_NAME (node)));
  344.       fprintf (outfile, " at %s line %d;",
  345.            DECL_SOURCE_FILE (node), DECL_SOURCE_LINE (node));
  346.       skip (indent);
  347.       prdeclmodeinfo (node);
  348.       prtypeinfo (node);
  349. #ifdef PRINT_LANG_DECL
  350.       print_lang_decl (node);
  351. #endif
  352.       skip (indent);
  353.       fprintf (outfile, " offset = %1d;", DECL_OFFSET (node));
  354.       if (DECL_VOFFSET (node) != NULL)
  355.     {
  356.       fputs ("voffset = ", outfile);
  357.       wruid (DECL_VOFFSET (node));
  358.       fprintf (outfile, "*%1d;", DECL_VOFFSET_UNIT (node));
  359.     }
  360.       part ("context", DECL_CONTEXT (node));
  361.       if (DECL_ARGUMENTS (node) || DECL_RESULT (node)
  362.       || DECL_INITIAL (node))
  363.     {
  364.       skip (indent);
  365.       part ("arguments", DECL_ARGUMENTS (node));
  366.       part ("result", DECL_RESULT (node));
  367.       if ((int) (DECL_INITIAL (node)) == 1)
  368.         fprintf (outfile, " initial = const 1;");
  369.       else
  370.         part ("initial", DECL_INITIAL (node));
  371.     }
  372. #ifdef PRINT_LANG_DECL
  373.       walk_lang_decl (node);
  374. #endif
  375.       part ("chain", TREE_CHAIN (node));
  376.       /* A Decl's chain contents is not part of the decl.  */
  377.       nochain = 1;
  378.       fputc ('\n', outfile);
  379.       cwalk (DECL_SIZE (node), node, indent);
  380.       walk (TREE_TYPE (node), node, indent);
  381.       walk (DECL_VOFFSET (node), node, indent);
  382.       walk (DECL_CONTEXT (node), node, indent);
  383.       walk (DECL_ARGUMENTS (node), node, indent);
  384.       walk (DECL_RESULT (node), node, indent);
  385.       if ((int) (DECL_INITIAL (node)) != 1)
  386.     walk (DECL_INITIAL (node), node, indent);
  387.       break;
  388.  
  389.     case 't':
  390.       if (TYPE_NAME (node) != NULL)
  391.     {
  392.       if (TREE_CODE (TYPE_NAME (node)) == IDENTIFIER_NODE)
  393.         fprintf (outfile, " type name = %s;",
  394.              IDENTIFIER_POINTER (TYPE_NAME (node)));
  395.       else if (TREE_CODE (TYPE_NAME (node)) == TYPE_DECL
  396.            && DECL_NAME (TYPE_NAME (node)) != NULL)
  397.         fprintf (outfile, " type name = %s;",
  398.              IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (node))));
  399.     }
  400.       prtypemodeinfo (node);
  401.       prtypeinfo (node);
  402. #ifdef PRINT_LANG_TYPE
  403.       print_lang_type (node);
  404. #endif
  405.       skip (indent);
  406.       part ("pointers_to_this", TYPE_POINTER_TO (node));
  407.       if (code == ARRAY_TYPE || code == SET_TYPE)
  408.     {
  409.       part ("domain", TYPE_DOMAIN (node));
  410.       cpart ("separation", TYPE_SEP (node), '*');
  411.       fprintf (outfile, "%d;", TYPE_SEP_UNIT (node));
  412.     }
  413.       else if (code == INTEGER_TYPE)
  414.     {
  415.       cpart ("min", TYPE_MIN_VALUE (node), ';');
  416.       cpart ("max", TYPE_MAX_VALUE (node), ';');
  417.       fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
  418.     }
  419.       else if (code == ENUMERAL_TYPE)
  420.     {
  421.       cpart ("min", TYPE_MIN_VALUE (node), ';');
  422.       cpart ("max", TYPE_MAX_VALUE (node), ';');
  423.       part ("values", TYPE_VALUES (node));
  424.       fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
  425.     }
  426.       else if (code == REAL_TYPE)
  427.     {
  428.       fprintf (outfile, "precision = %d;", TYPE_PRECISION (node));
  429.     }
  430.       else if (code == RECORD_TYPE
  431.            || code == UNION_TYPE)
  432.     {
  433.       part ("fields", TYPE_FIELDS (node));
  434.     }
  435.       else if (code == FUNCTION_TYPE)
  436.     {
  437.       part ("arg_types", TYPE_ARG_TYPES (node));
  438.     }
  439.       else if (code == METHOD_TYPE)
  440.     {
  441.       part ("arg_types", TYPE_ARG_TYPES (node));
  442.     }
  443. #ifdef PRINT_LANG_TYPE
  444.       walk_lang_type (node);
  445. #endif
  446.       part ("chain", TREE_CHAIN (node));
  447.       /* A type's chain's contents are not printed because the chain of types
  448.      is not part of the meaning of any particular type.  */
  449.       nochain = 1;
  450.       fputc ('\n', outfile);
  451.       cwalk (TYPE_SIZE (node), node, indent);
  452.       walk (TREE_TYPE (node), node, indent);
  453.       walk (TYPE_VALUES (node), node, indent);
  454.       walk (TYPE_SEP (node), node, indent);
  455.       walk (TYPE_POINTER_TO (node), node, indent);
  456.       break;
  457.  
  458.     case 'e':
  459.     case 'r':
  460.       prtypeinfo (node);
  461.       fputs (" ops =", outfile);
  462.       first_rtl = len = tree_code_length[(int) code];
  463.       /* These kinds of nodes contain rtx's, not trees,
  464.      after a certain point.  Print the rtx's as rtx's.  */
  465.       switch (code)
  466.     {
  467.     case SAVE_EXPR:
  468.       first_rtl = 1;
  469.       break;
  470.     case CALL_EXPR:
  471.       first_rtl = 2;
  472.       break;
  473.     case METHOD_CALL_EXPR:
  474.       first_rtl = 3;
  475.       break;
  476.     case WITH_CLEANUP_EXPR:
  477.       /* Should be defined to be 2.  */
  478.       first_rtl = 1;
  479.       break;
  480.     case RTL_EXPR:
  481.       first_rtl = 0;
  482.     }
  483.       for (i = 0; i < len; i++)
  484.     {
  485.       if (i >= first_rtl)
  486.         {
  487.           skip (indent);
  488.           if (TREE_OPERAND (node, i))
  489.         print_rtl (outfile, TREE_OPERAND (node, i));
  490.           else
  491.         fprintf (outfile, "(nil)");
  492.           fprintf (outfile, "\n");
  493.         }
  494.       else
  495.         {
  496.           fputs (" ", outfile);
  497.           wruid (TREE_OPERAND (node, i));
  498.           fputs (";", outfile);
  499.         }
  500.     }
  501.       part ("chain", TREE_CHAIN (node));
  502.       fputc ('\n', outfile);
  503.       walk (TREE_TYPE (node), node, indent);
  504.       for (i = 0; i < len && i < first_rtl; i++)
  505.     walk (TREE_OPERAND (node, i), node, indent);
  506.       break;
  507.  
  508.     case 's':
  509.       prtypeinfo (node);
  510.       fprintf (outfile, " at %s line %d;",
  511.            STMT_SOURCE_FILE (node), STMT_SOURCE_LINE (node));
  512.       switch (TREE_CODE (node))
  513.     {
  514.     case IF_STMT:
  515.       part ("cond", STMT_COND (node));
  516.       part ("then", STMT_THEN (node));
  517.       part ("else", STMT_ELSE (node));
  518.       break;
  519.  
  520.     case LET_STMT:
  521.     case WITH_STMT:
  522.       part ("vars", STMT_VARS (node));
  523.       part ("tags", STMT_TYPE_TAGS (node));
  524.       part ("supercontext", STMT_SUPERCONTEXT (node));
  525.       part ("bind_size", STMT_BIND_SIZE (node));
  526.       part ("body", STMT_BODY (node));
  527.       part ("subblocks", STMT_SUBBLOCKS (node));
  528.       break;
  529.  
  530.     case CASE_STMT:
  531.       part ("case_index", STMT_CASE_INDEX (node));
  532.       part ("case_list", STMT_CASE_LIST (node));
  533.       break;
  534.  
  535.     default:
  536.       part ("body", STMT_BODY (node));
  537.       break;
  538.     }
  539.       part ("chain", TREE_CHAIN (node));
  540.       fputc ('\n', outfile);
  541.       walk (TREE_TYPE (node), node, indent);
  542.       switch (TREE_CODE (node))
  543.     {
  544.     case IF_STMT:
  545.       walk (STMT_COND (node), node, indent);
  546.       walk (STMT_THEN (node), node, indent);
  547.       walk (STMT_ELSE (node), node, indent);
  548.       break;
  549.  
  550.     case LET_STMT:
  551.     case WITH_STMT:
  552.       walk (STMT_VARS (node), node, indent);
  553.       walk (STMT_TYPE_TAGS (node), node, indent);
  554.       walk (STMT_SUPERCONTEXT (node), node, indent);
  555.       walk (STMT_BIND_SIZE (node), node, indent);
  556.       walk (STMT_BODY (node), node, indent);
  557.       walk (STMT_SUBBLOCKS (node), node, indent);
  558.       break;
  559.  
  560.     case CASE_STMT:
  561.       walk (STMT_CASE_INDEX (node), node, indent);
  562.       walk (STMT_CASE_LIST (node), node, indent);
  563.       break;
  564.  
  565.     default:
  566.       walk (STMT_BODY (node), node, indent);
  567.       break;
  568.     }
  569.       break;
  570.  
  571.     case 'c':
  572.       switch (code)
  573.     {
  574.     case INTEGER_CST:
  575.       if (TREE_INT_CST_HIGH (node) == 0)
  576.         fprintf (outfile, " = %1u;", TREE_INT_CST_LOW (node));
  577.       else if (TREE_INT_CST_HIGH (node) == -1
  578.            && TREE_INT_CST_LOW (node) != 0)
  579.         fprintf (outfile, " = -%1u;", -TREE_INT_CST_LOW (node));
  580.       else
  581.         fprintf (outfile, " = 0x%x%08x;",
  582.              TREE_INT_CST_HIGH (node),
  583.              TREE_INT_CST_LOW (node));
  584.       break;
  585.  
  586.     case REAL_CST:
  587. #ifndef REAL_IS_NOT_DOUBLE
  588.       fprintf (outfile, " = %e;", TREE_REAL_CST (node));
  589. #else
  590.       {
  591.         int i;
  592.         char *p = (char *) &TREE_REAL_CST (node);
  593.         fprintf (outfile, " = 0x");
  594.         for (i = 0; i < sizeof TREE_REAL_CST (node); i++)
  595.           fprintf (outfile, "%02x", *p++);
  596.         fprintf (outfile, ";");
  597.       }
  598. #endif /* REAL_IS_NOT_DOUBLE */
  599.       break;
  600.  
  601.     case COMPLEX_CST:
  602.       part ("realpart", TREE_REALPART (node));
  603.       part ("imagpart", TREE_IMAGPART (node));
  604.       walk (TREE_REALPART (node), node, indent);
  605.       walk (TREE_IMAGPART (node), node, indent);
  606.       break;
  607.  
  608.     case STRING_CST:
  609.       fprintf (outfile, " = \"%s\";", TREE_STRING_POINTER (node));
  610.     }
  611.       prtypeinfo (node);
  612.       part ("chain", TREE_CHAIN (node));
  613.       fputc ('\n', outfile);
  614.       walk (TREE_TYPE (node), node, indent);
  615.       break;
  616.  
  617.     case 'x':
  618.       if (code == IDENTIFIER_NODE)
  619.     {
  620.       fprintf (outfile, " = %s;\n", IDENTIFIER_POINTER (node));
  621.       nochain = 1;
  622.     }
  623.       else if (code == TREE_LIST)
  624.     {
  625.       prtypeinfo (node);
  626.       part ("purpose", TREE_PURPOSE (node));
  627.       part ("value", TREE_VALUE (node));
  628.       part ("chain", TREE_CHAIN (node));
  629.       fputc ('\n', outfile);
  630.       walk (TREE_TYPE (node), node, indent);
  631.       walk (TREE_PURPOSE (node), node, indent);
  632.       walk (TREE_VALUE (node), node, indent);
  633.     }
  634.       else if (code == OP_IDENTIFIER)
  635.     {
  636.       prtypeinfo (node);
  637.       part ("op1", TREE_PURPOSE (node));
  638.       part ("op2", TREE_VALUE (node));
  639.       part ("chain", TREE_CHAIN (node));
  640.       fputc ('\n', outfile);
  641.       walk (TREE_TYPE (node), node, indent);
  642.       walk (TREE_PURPOSE (node), node, indent);
  643.       walk (TREE_VALUE (node), node, indent);
  644.     }
  645.       else if (code == ERROR_MARK)
  646.     fputc ('\n', outfile);
  647.       else abort ();
  648.  
  649.       break;
  650.  
  651.     default:
  652.       abort ();
  653.     } /* switch */
  654.  
  655.   if (TREE_CHAIN (node) != NULL && ! nochain)
  656.     dump (TREE_CHAIN (node), indent);
  657. }
  658.